![]() |
![]() |
![]() |
Les modèles PaliGemma disposent de fonctionnalités multimodales, ce qui vous permet de générer des sorties à l'aide de données d'entrée textuelles et d'images. Vous pouvez utiliser les données d'image avec ces modèles pour fournir un contexte supplémentaire à vos requêtes ou pour analyser le contenu des images. Ce tutoriel vous explique comment utiliser PaliGemma avec Keras pour analyser des images et répondre à des questions à leur sujet.
Contenu de ce notebook
Ce notebook utilise PaliGemma avec Keras et vous explique comment:
- Installer Keras et les dépendances requises
- Téléchargez
PaliGemmaCausalLM
, une variante pré-entrainée de PaliGemma pour la modélisation du langage visuel causal, et utilisez-la pour créer un modèle. - Tester la capacité du modèle à inférer des informations sur les images fournies
Avant de commencer
Avant de suivre ce notebook, vous devez connaître le code Python et la façon dont les grands modèles de langage (LLM) sont entraînés. Vous n'avez pas besoin de connaître Keras, mais des connaissances de base sur Keras sont utiles lorsque vous lisez l'exemple de code.
Configuration
Les sections suivantes expliquent les étapes préliminaires à suivre pour qu'un notebook utilise un modèle PaliGemma, y compris l'accès au modèle, l'obtention d'une clé API et la configuration de l'environnement d'exécution du notebook.
Accéder à PaliGemma
Avant d'utiliser PaliGemma pour la première fois, vous devez demander l'accès au modèle via Kaggle en procédant comme suit:
- Connectez-vous à Kaggle ou créez un compte Kaggle si vous n'en avez pas déjà un.
- Accédez à la fiche de modèle PaliGemma, puis cliquez sur Demander l'accès.
- Remplissez le formulaire de consentement et acceptez les conditions d'utilisation.
Configurer votre clé API
Pour utiliser PaliGemma, vous devez fournir votre nom d'utilisateur Kaggle et une clé API Kaggle.
Pour générer une clé API Kaggle, ouvrez la page Settings (Paramètres) dans Kaggle, puis cliquez sur Create New Token (Créer un jeton). Cela déclenche le téléchargement d'un fichier kaggle.json
contenant vos identifiants d'API.
Ensuite, dans Colab, sélectionnez Secrets (Secrets) 🔑 dans le volet de gauche, puis ajoutez votre nom d'utilisateur Kaggle et votre clé API Kaggle. Stockez votre nom d'utilisateur sous le nom KAGGLE_USERNAME
et votre clé API sous le nom KAGGLE_KEY
.
Sélectionner l'environnement d'exécution
Pour suivre ce tutoriel, vous devez disposer d'un environnement d'exécution Colab avec suffisamment de ressources pour exécuter le modèle PaliGemma. Dans ce cas, vous pouvez utiliser un GPU T4:
- En haut à droite de la fenêtre Colab, cliquez sur le menu déroulant ▾ (Options de connexion supplémentaires).
- Sélectionnez Modifier le type d'environnement d'exécution.
- Sous Hardware accelerator (Accélérateur matériel), sélectionnez T4 GPU (GPU T4).
Définir des variables d'environnement
Définissez les variables d'environnement pour KAGGLE_USERNAME
, KAGGLE_KEY
et KERAS_BACKEND
.
import os
from google.colab import userdata
# Set up environmental variables
os.environ["KAGGLE_USERNAME"] = userdata.get('KAGGLE_USERNAME')
os.environ["KAGGLE_KEY"] = userdata.get('KAGGLE_KEY')
os.environ["KERAS_BACKEND"] = "jax"
Installer Keras
Exécutez la cellule ci-dessous pour installer Keras.
pip install -U -q keras-nlp keras-hub kagglehub
Importer des dépendances et configurer Keras
Installez les dépendances nécessaires à ce notebook et configurez le backend de Keras. Vous allez également définir Keras pour qu'il utilise bfloat16
afin que le framework utilise moins de mémoire.
import keras
import keras_hub
import numpy as np
import PIL
import requests
import io
import matplotlib
import re
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
keras.config.set_floatx("bfloat16")
Charger le modèle
Maintenant que vous avez tout configuré, vous pouvez télécharger le modèle pré-entraîné et créer des méthodes utilitaires pour aider votre modèle à générer ses réponses.
À cette étape, vous téléchargez un modèle à l'aide de PaliGemmaCausalLM
depuis Keras Hub. Ce cours vous aide à gérer et à exécuter la structure du modèle de langage visuel causal de PaliGemma. Un modèle de langage visuel causal prédit le jeton suivant en fonction des jetons précédents. Keras Hub fournit des implémentations de nombreuses architectures de modèles populaires.
Créez le modèle à l'aide de la méthode from_preset
et imprimez son résumé. Cette opération prend environ une minute.
paligemma = keras_hub.models.PaliGemmaCausalLM.from_preset("kaggle://keras/paligemma2/keras/pali_gemma2_mix_3b_224")
paligemma.summary()
Créer des méthodes utilitaires
Pour vous aider à générer des réponses à partir de votre modèle, créez deux méthodes utilitaires:
crop_and_resize
:méthode d'assistance pourread_img
. Cette méthode redimensionne et recadre l'image à la taille transmise afin que l'image finale soit redimensionnée sans déformer ses proportions.read_img
:méthode d'assistance pourread_img_from_url
. C'est cette méthode qui ouvre réellement l'image, la redimensionne pour qu'elle s'adapte aux contraintes du modèle et la place dans un tableau pouvant être interprété par le modèle.read_img_from_url
:importe une image via une URL valide. Vous avez besoin de cette méthode pour transmettre l'image au modèle.
Vous utiliserez read_img_from_url
à l'étape suivante de ce notebook.
def crop_and_resize(image, target_size):
width, height = image.size
source_size = min(image.size)
left = width // 2 - source_size // 2
top = height // 2 - source_size // 2
right, bottom = left + source_size, top + source_size
return image.resize(target_size, box=(left, top, right, bottom))
def read_image(url, target_size):
contents = io.BytesIO(requests.get(url).content)
image = PIL.Image.open(contents)
image = crop_and_resize(image, target_size)
image = np.array(image)
# Remove alpha channel if necessary.
if image.shape[2] == 4:
image = image[:, :, :3]
return image
def parse_bbox_and_labels(detokenized_output: str):
matches = re.finditer(
'<loc(?P<y0>\d\d\d\d)><loc(?P<x0>\d\d\d\d)><loc(?P<y1>\d\d\d\d)><loc(?P<x1>\d\d\d\d)>'
' (?P<label>.+?)( ;|$)',
detokenized_output,
)
labels, boxes = [], []
fmt = lambda x: float(x) / 1024.0
for m in matches:
d = m.groupdict()
boxes.append([fmt(d['y0']), fmt(d['x0']), fmt(d['y1']), fmt(d['x1'])])
labels.append(d['label'])
return np.array(boxes), np.array(labels)
def display_boxes(image, boxes, labels, target_image_size):
h, l = target_size
fig, ax = plt.subplots()
ax.imshow(image)
for i in range(boxes.shape[0]):
y, x, y2, x2 = (boxes[i]*h)
width = x2 - x
height = y2 - y
# Create a Rectangle patch
rect = patches.Rectangle((x, y),
width,
height,
linewidth=1,
edgecolor='r',
facecolor='none')
# Add label
plt.text(x, y, labels[i], color='red', fontsize=12)
# Add the patch to the Axes
ax.add_patch(rect)
plt.show()
def display_segment_output(image, bounding_box, segment_mask, target_image_size):
# Initialize a full mask with the target size
full_mask = np.zeros(target_image_size, dtype=np.uint8)
target_width, target_height = target_image_size
for bbox, mask in zip(bounding_box, segment_mask):
y1, x1, y2, x2 = bbox
x1 = int(x1 * target_width)
y1 = int(y1 * target_height)
x2 = int(x2 * target_width)
y2 = int(y2 * target_height)
# Ensure mask is 2D before converting to Image
if mask.ndim == 3:
mask = mask.squeeze(axis=-1)
mask = Image.fromarray(mask)
mask = mask.resize((x2 - x1, y2 - y1), resample=Image.NEAREST)
mask = np.array(mask)
binary_mask = (mask > 0.5).astype(np.uint8)
# Place the binary mask onto the full mask
full_mask[y1:y2, x1:x2] = np.maximum(full_mask[y1:y2, x1:x2], binary_mask)
cmap = plt.get_cmap('jet')
colored_mask = cmap(full_mask / 1.0)
colored_mask = (colored_mask[:, :, :3] * 255).astype(np.uint8)
if isinstance(image, Image.Image):
image = np.array(image)
blended_image = image.copy()
mask_indices = full_mask > 0
alpha = 0.5
for c in range(3):
blended_image[:, :, c] = np.where(mask_indices,
(1 - alpha) * image[:, :, c] + alpha * colored_mask[:, :, c],
image[:, :, c])
fig, ax = plt.subplots()
ax.imshow(blended_image)
plt.show()
Générer une sortie
Après avoir chargé le modèle et créé des méthodes utilitaires, vous pouvez lui fournir des données d'image et de texte pour générer des réponses. Les modèles PaliGemma sont entraînés avec une syntaxe de requête spécifique pour des tâches spécifiques, telles que answer
, caption
et detect
. Pour en savoir plus sur la syntaxe des tâches d'invite PaliGemma, consultez Invite PaliGemma et instructions système.
Préparez une image à utiliser dans une requête de génération à l'aide du code suivant pour charger une image de test dans un objet:
target_size = (224, 224)
image_url = 'https://storage.googleapis.com/keras-cv/models/paligemma/cow_beach_1.png'
cow_image = read_image(image_url, target_size)
matplotlib.pyplot.imshow(cow_image)
Répondre dans une langue spécifique
L'exemple de code suivant montre comment demander au modèle PaliGemma des informations sur un objet apparaissant dans une image fournie. Cet exemple utilise la syntaxe answer {lang}
et affiche des questions supplémentaires dans d'autres langues:
prompt = 'answer en where is the cow standing?\n'
# prompt = 'svar no hvor står kuen?\n'
# prompt = 'answer fr quelle couleur est le ciel?\n'
# prompt = 'responda pt qual a cor do animal?\n'
output = paligemma.generate(
inputs={
"images": cow_image,
"prompts": prompt,
}
)
print(output)
Utiliser l'invite detect
L'exemple de code suivant utilise la syntaxe de requête detect
pour localiser un objet dans l'image fournie. Le code utilise les fonctions parse_bbox_and_labels()
et display_boxes()
définies précédemment pour interpréter la sortie du modèle et afficher les rectangles de délimitation générés.
prompt = 'detect cow\n'
output = paligemma.generate(
inputs={
"images": cow_image,
"prompts": prompt,
}
)
boxes, labels = parse_bbox_and_labels(output)
display_boxes(cow_image, boxes, labels, target_size)
Utiliser l'invite segment
L'exemple de code suivant utilise la syntaxe d'invite segment
pour localiser la zone d'une image occupée par un objet. Il utilise la bibliothèque Google big_vision
pour interpréter la sortie du modèle et générer un masque pour l'objet segmenté.
Avant de commencer, installez la bibliothèque big_vision
et ses dépendances, comme indiqué dans cet exemple de code:
import os
import sys
# TPUs with
if "COLAB_TPU_ADDR" in os.environ:
raise "It seems you are using Colab with remote TPUs which is not supported."
# Fetch big_vision repository if python doesn't know about it and install
# dependencies needed for this notebook.
if not os.path.exists("big_vision_repo"):
!git clone --quiet --branch=main --depth=1 \
https://github.com/google-research/big_vision big_vision_repo
# Append big_vision code to python import path
if "big_vision_repo" not in sys.path:
sys.path.append("big_vision_repo")
# Install missing dependencies. Assume jax~=0.4.25 with GPU available.
!pip3 install -q "overrides" "ml_collections" "einops~=0.7" "sentencepiece"
Pour cet exemple de segmentation, chargez et préparez une autre image qui inclut un chat.
cat = read_image('https://big-vision-paligemma.hf.space/file=examples/barsik.jpg', target_size)
matplotlib.pyplot.imshow(cat)
Voici une fonction pour vous aider à analyser la sortie du segment de PaliGemma
import big_vision.evaluators.proj.paligemma.transfers.segmentation as segeval
reconstruct_masks = segeval.get_reconstruct_masks('oi')
def parse_segments(detokenized_output: str) -> tuple[np.ndarray, np.ndarray]:
matches = re.finditer(
'<loc(?P<y0>\d\d\d\d)><loc(?P<x0>\d\d\d\d)><loc(?P<y1>\d\d\d\d)><loc(?P<x1>\d\d\d\d)>'
+ ''.join(f'<seg(?P<s{i}>\d\d\d)>' for i in range(16)),
detokenized_output,
)
boxes, segs = [], []
fmt_box = lambda x: float(x) / 1024.0
for m in matches:
d = m.groupdict()
boxes.append([fmt_box(d['y0']), fmt_box(d['x0']), fmt_box(d['y1']), fmt_box(d['x1'])])
segs.append([int(d[f's{i}']) for i in range(16)])
return np.array(boxes), np.array(reconstruct_masks(np.array(segs)))
Interroger PaliGemma pour segmenter le chat dans l'image
prompt = 'segment cat\n'
output = paligemma.generate(
inputs={
"images": cat,
"prompts": prompt,
}
)
Visualiser le masque généré à partir de PaliGemma
bboxes, seg_masks = parse_segments(output)
display_segment_output(cat, bboxes, seg_masks, target_size)
Requêtes par lots
Vous pouvez fournir plusieurs commandes d'invite dans une même invite en tant que lot d'instructions. L'exemple suivant montre comment structurer le texte de votre requête pour fournir plusieurs instructions.
prompts = [
'answer en where is the cow standing?\n',
'answer en what color is the cow?\n',
'describe en\n',
'detect cow\n',
'segment cow\n',
]
images = [cow_image, cow_image, cow_image, cow_image, cow_image]
outputs = paligemma.generate(
inputs={
"images": images,
"prompts": prompts,
}
)
for output in outputs:
print(output)